// pollingUtils.js
class AsyncTaskPoller {
    constructor(api) {
        this.pollingTasks = new Map();
        this.api = api;
    }

    async asyncTaskPolling(taskId, callback, pollingTime = 1000, api_provider = null, clearByTheEnd = false) {
        let fromIndex = 0;
        let result = null;
        let pollInterval = pollingTime;

        // 设置taskInfo的promise信息
        const taskInfo = {
            isPolling: true,
            stopPromise: null,
            stopResolve: null
        };
        taskInfo.stopPromise = new Promise((resolve) => {
            taskInfo.stopResolve = resolve;
        });
        this.pollingTasks.set(taskId, taskInfo);

        // 轮询的代码
        const pollQueue = async () => {
            if (!taskInfo.isPolling) {
                return false;
            }

            try {
                let queueParams = {
                    task_id: taskId,
                    from_index: fromIndex
                };

                let provider = api_provider || this.api.provider;
                if (provider == 'local') {
                    result = await this.api.local.invoke('PeekQueue', queueParams);
                } else if (provider == 'remote') {
                    result = await this.api.remotes.invoke('PeekQueue', queueParams);
                }

                // const timestamp = new Date().toISOString();
                // console.log(`[${timestamp}] PeekQueue result result.msg = `, result.msg, 'queueParams = ', queueParams);

                if (result.code !== 0) {
                    throw new Error(result.msg || 'Unknown error');
                }

                let hasNewMessages = false;
                for (let i = 0; i < result.msg.length; i++, fromIndex++) {
                    let msg = result.msg[i];
                    try {
                        msg = JSON.parse(msg.message);
                        // console.log(`[${ timestamp }]msg = `, msg);
                    } catch (jsonError) {
                        console.warn('JSON parse error:', jsonError);
                        continue;
                    }

                    callback(taskId, msg);
                    hasNewMessages = true;

                    const endEvents = ['result', 'end', 'parse_end'];
                    if (endEvents.includes(msg.event)) {
                        this.stopPolling(taskId);
                        return false;
                    }
                }

                // 调整轮询间隔
                if (hasNewMessages) {
                    pollInterval = pollingTime;
                } else {
                    // pollInterval = Math.min(pollInterval * 2, 30000);
                    pollInterval = pollingTime;
                }

                return true;
            } catch (error) {
                console.log('Polling error:', error);
                // callback(taskId, null);
                this.stopPolling(taskId);
                return false;
            }
        };

        // 开始轮询
        while (await pollQueue()) {
            await Promise.race([new Promise((resolve) => setTimeout(resolve, pollInterval)), taskInfo.stopPromise]);
        }

        taskInfo.stopResolve && taskInfo.stopResolve();
        this.pollingTasks.delete(taskId);

        // 结束轮询后，清理队列
        if (clearByTheEnd) {
            let provider = api_provider || this.api.provider;
            if (provider == 'local') {
                await this.api.local.invoke('ClearQueue', { task_id: taskId });
            } else if (provider == 'remote') {
                await this.api.remotes.invoke('ClearQueue', { task_id: taskId });
            }
        }
    }

    async stopPolling(taskId) {
        const taskInfo = this.pollingTasks.get(taskId);
        if (taskInfo && taskInfo.isPolling) {
            taskInfo.isPolling = false;
            await taskInfo.stopPromise;
            // console.log(`Polling stopped for task: ${ taskId } `);
        }
    }

    async stopAllPolling() {
        const stopPromises = [];
        for (let [taskId, taskInfo] of this.pollingTasks) {
            // console.log(`stopAllPolling taskId = `, taskId);
            if (taskInfo.isPolling) {
                taskInfo.isPolling = false;
                stopPromises.push(taskInfo.stopPromise);
            }
        }

        await Promise.all(stopPromises);
        // console.log('Stopped all polling tasks');
    }
}

export { AsyncTaskPoller };
